package com.miaoshaoproject.service.impl;

import com.miaoshaoproject.dao.OrderDOMapper;
import com.miaoshaoproject.dao.SequenceDOMapper;
import com.miaoshaoproject.dao.StockLogDOMapper;
import com.miaoshaoproject.dataobject.OrderDO;
import com.miaoshaoproject.dataobject.SequenceDO;
import com.miaoshaoproject.dataobject.StockLogDO;
import com.miaoshaoproject.error.BussinessException;
import com.miaoshaoproject.error.EmBussinessError;
import com.miaoshaoproject.mq.MqProducer;
import com.miaoshaoproject.service.model.ItemModel;
import com.miaoshaoproject.service.model.OrderModel;
import com.miaoshaoproject.service.model.UserModel;
import com.miaoshaoproject.service.ItemService;
import com.miaoshaoproject.service.OrderService;
import com.miaoshaoproject.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private ItemService itemService;
    @Autowired
    private UserService userService;
    @Autowired
    private OrderDOMapper orderDOMapper;
    @Autowired
    private SequenceDOMapper sequenceDOMapper;
    @Autowired
    private StockLogDOMapper stockLogDOMapper;

    @Override
    @Transactional
    public OrderModel createOrder(Integer userId, Integer itemId,Integer promoId, Integer amount,String stockLogId) throws BussinessException {
        //1、校验下单状态，下单的商品是否存在，用户是否合法，购买数量是否正确
        //ItemModel itemModel=itemService.getItemById(itemId);
        ItemModel itemModel=itemService.getItemByIdInCache(itemId);
//        if(itemModel==null){
//            throw new BussinessException(EmBussinessError.PARAMETER_VALIDATION_ERROR,"商品信息不存在");
//        }
//
//        //UserModel userModel=userService.getUserById(userId);
//        UserModel userModel=userService.getUserModelByIdInCache(userId);
//        if(userModel==null){
//            throw new BussinessException(EmBussinessError.PARAMETER_VALIDATION_ERROR,"用户信息不存在");
//        }

        if(amount<=0 || amount>99){
            throw new BussinessException(EmBussinessError.PARAMETER_VALIDATION_ERROR,"数量信息不存在");
        }

        //校验活动信息

//        if(promoId!=null){
//            //校验对应活动是否存在这个适用商品
//            if(promoId.intValue()!=itemModel.getPromoModel().getId()){
//                throw new BussinessException(EmBussinessError.PARAMETER_VALIDATION_ERROR,"活动信息不存在");
//            }
//            //校验活动是否正在进行中
//            else if (itemModel.getPromoModel().getStatus().intValue()!=2){
//                throw new BussinessException(EmBussinessError.PARAMETER_VALIDATION_ERROR,"活动还未开始");
//            }
//        }

        //2、落单减库存
        boolean result=itemService.decreaseStock(itemId,amount);
        if(!result){
            throw new BussinessException(EmBussinessError.STOCK_NOT_ENOUGH);
        }
        //3、订单入库
        OrderModel orderModel=new OrderModel();
        orderModel.setUserId(userId);
        orderModel.setItemId(itemId);
        orderModel.setAmount(amount);
        if (promoId!=null){
            orderModel.setItemPrice(itemModel.getPromoModel().getPromoItemPrice());
        }else{
            orderModel.setItemPrice(itemModel.getPrice());
        }
        orderModel.setPromoId(promoId);
        orderModel.setOrderPrice(itemModel.getPrice().multiply(new BigDecimal(amount)));

        //生成交易流水号
        orderModel.setId(generateOrderNo());
        OrderDO orderDO =convertFromOrderModel(orderModel);
        orderDOMapper.insertSelective(orderDO);
        //加上销量
        itemService.increaseSales(itemId,amount);
        //设置存库流水状态为成功
        StockLogDO stockLogDO=stockLogDOMapper.selectByPrimaryKey(stockLogId);
        if (stockLogDO==null){
            throw new BussinessException(EmBussinessError.UNKNOWN_ERROR);
        }
        stockLogDO.setStatus(2);
        stockLogDOMapper.updateByPrimaryKeySelective(stockLogDO);


        //大事务提交后再执行
//        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
//            @Override
//            public void afterCommit(){
//                //异步更新库存
//                boolean mqResult=itemService.asyncDecreaseStock(itemId,amount);
//                /*if (!mqResult) {
//                    itemService.increaseStock(itemId,amount);
//                    throw new BussinessException(EmBussinessError.MQ_SEND_FAIL);
//                }*/
//            }
//        });


        //4、返回前端
        return orderModel;
    }
    private OrderDO convertFromOrderModel(OrderModel orderModel){
       if(orderModel==null){
           return null;
       }
       OrderDO orderDO=new OrderDO();
        BeanUtils.copyProperties(orderModel,orderDO);
        orderDO.setItemPrice(orderModel.getItemPrice().doubleValue());
        orderDO.setOrderPrice(orderModel.getOrderPrice().doubleValue());
        return  orderDO;
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    String generateOrderNo(){
        //订单号有16位
        StringBuilder stringBuilder=new StringBuilder();
        //前8位为时间信息，年月日
        LocalDateTime now=LocalDateTime.now();
        String nowDate=now.format(DateTimeFormatter.ISO_DATE).replaceAll("-","");
        stringBuilder.append(nowDate);
        //中间6位为自增序列
        //获取当前sequence
        int sequence=0;
        SequenceDO sequenceDO=sequenceDOMapper.getSequenceByName("order_info");
        sequence=sequenceDO.getCurrentValue();
        sequenceDO.setCurrentValue(sequenceDO.getCurrentValue()+sequenceDO.getStep());
        sequenceDOMapper.updateByPrimaryKey(sequenceDO);
        String sequenceStr=String.valueOf(sequence);
        for(int i=0;i<6-sequenceStr.length();i++){
            stringBuilder.append(0);
        }
        stringBuilder.append(sequenceStr);
        //最后两位为分库分表位
        stringBuilder.append("00");
        return  stringBuilder.toString();
    }

}
